Skip to content

Add console#383

Open
zhoujh01 wants to merge 1 commit intomainfrom
add_console
Open

Add console#383
zhoujh01 wants to merge 1 commit intomainfrom
add_console

Conversation

@zhoujh01
Copy link
Collaborator

@zhoujh01 zhoujh01 commented Mar 2, 2026

  1. 背景与目标
  • 为 OpenViking 提供一个可独立启动的 Console 示例,降低调试、演示和运维操作门槛。
  • 将核心管理能力(文件、检索、资源入库、多租户、监控)统一到可视化入口,提升操作效率。
  • 在保证易用性的同时,强化写操作安全护栏,避免误操作风险。
  1. 方案概述(架构)
  • 采用“三层结构”:前端控制台(静态页面) + Console BFF(FastAPI) + OpenViking 主服务。
  • 前端统一请求 /console/api/v1/,BFF 再转发到 OpenViking /api/v1/,实现接口收敛和统一错误处理。
  • BFF 启用请求头白名单透传(如 X-API-Key),并对写操作统一做后端拦截。
  1. 本次新增能力(重点)
  • 文件系统能力

    • 支持 ls/tree/stat 浏览与元信息查看。
    • 支持目录跳转、回退、上级、刷新、列表排序等交互能力。
    • 支持文件内容读取与详情查看。
  • 检索能力(Find)

    • 支持 Query + 可选 Target URI 的语义检索。
    • 检索结果表格化展示,支持动态列与排序。
  • 资源入库能力(Add Resource)

    • 支持“按路径入库”。
    • 支持“先上传临时文件,再发起入库”。
    • 支持附带参数(wait/strict/timeout/include/exclude/reason/instruction 等)。
  • 多租户管理能力(Tenants)

    • 账户:创建、删除、列表、过滤、排序。
    • 用户:新增、删除、角色变更、API Key 重置。
    • 账户与用户联动查看,形成完整操作闭环。
  • 监控能力(Monitor)

    • 支持查看 system status。
    • 支持查看 observer(system) 组件状态。
  • 会话与鉴权能力(Settings)

    • 支持在页面设置 X-API-Key,写入 session storage。
    • 所有请求自动携带 key,便于多次调试与演示。
  1. 安全与风险控制设计
  • 写操作总开关:默认只读;仅在启动参数显式开启 --write-enabled 时允许写入。
  • 前后端双重防护:
    • 后端:所有写接口统一校验 write_enabled。
    • 前端:读取 runtime capabilities 后自动禁用写按钮。
  • 高风险操作二次确认:多租户删除/变更操作需要输入确认文本,降低误触风险。
  • 代理透传最小化:仅放行必要 Header,避免无关敏感信息穿透。
  1. 交付价值
  • 对研发:提供统一可视化调试入口,减少手工 API 调用成本。
  • 对运维/支持:账户与用户管理、状态排查可在单页面完成。
  • 对演示:具备完整业务链路(浏览→检索→入库→管理→监控),便于对外展示产品能力。
  • 对平台治理:默认只读 + 显式写开关 + 危险操作确认,兼顾效率与安全。
  1. 当前边界与限制
  • 当前定位为 examples 下的示例服务,尚未纳入正式发布与 CLI 主链路。
  • 鉴权以 X-API-Key 为主,企业级权限细粒度策略可在后续增强。
  • 暂未覆盖完整自动化测试矩阵(后续建议补齐 API 代理层与关键前端交互用例)。
  1. 下一步建议

  2. 产品化接入:评估并推进从 example 向正式控制台模块演进。

  3. 安全增强:补充审计日志、操作人追踪、可配置确认策略。

  4. 可观测性增强:增加更多 observer 维度与失败请求诊断信息。

  5. 测试补强:补充 BFF 路由单测 + 关键端到端 UI 用例。

  6. 体验优化:权限感知 UI(按角色显示能力)、批量操作与更细粒度筛选。

Copy link
Contributor

@r266-tech r266-tech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢 @zhoujh01 的工作,Console 补齐了 OV 一直缺少的可视化运维入口,对日常调试和演示都很有价值。整体看了一遍代码,分享几点建议:

👍 做得好的地方

  • 写操作安全护栏设计很扎实--write-enabled 启动参数 + 后端 _ensure_write_enabled 逐路由拦截 + 前端根据 /runtime/capabilities 动态禁用按钮,三层防护覆盖全面。
  • Header 白名单透传_ALLOWED_FORWARD_HEADERS)比全量透传安全得多,最小化暴露面。
  • 前端 XSS 防护意识好:动态数据一律用 textContent 而非 innerHTMLinnerHTML 仅用于清空或插入静态片段。
  • URI 参数统一 encodeURIComponent,降低注入风险。

🔧 几个建议

1. httpx.AsyncClient 缺少 shutdown 清理

app.state.upstream_clientcreate_console_app 中创建但没有对应的关闭逻辑。建议加一个 FastAPI lifespan handler:

from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app: FastAPI):
    yield
    await app.state.upstream_client.aclose()

不加的话,进程退出时可能会有 ResourceWarning,在长期运行场景下也可能有连接泄漏。

2. CORS allow_origins=["*"] + allow_credentials=True 组合

这个组合在浏览器层面会被拒绝(spec 要求 credentials 模式下 origin 不能是通配符),实际效果可能不符合预期。建议:

  • 如果是本地开发,默认用 ["http://127.0.0.1:8020"] 即可
  • 或者去掉 allow_credentials=True(Console 用的是 Header 鉴权而非 Cookie,不需要 credentials)

3. 建议补充 BFF 路由层测试

当前 PR 3874 行新增代码、0 个测试文件。BFF 作为代理层,最容易出问题的是路由映射和写操作拦截。建议至少覆盖:

  • 写操作在 write_enabled=False 时返回 403
  • Header 白名单只透传允许的 key
  • 上游不可达时返回 502

httpx.MockTransport + create_console_app(upstream_transport=...) 就能写纯单元测试,不依赖真实 OV 服务。upstream_transport 参数已经预留了,加测试会很顺畅。

4. 前端单文件 1976 行

作为 example 可以理解,但如果后续要产品化(PR 描述也提到了),建议早点拆分模块(至少按 panel 拆文件),否则维护成本会快速上升。


总体来说架构清晰、安全意识到位,作为 examples 下的示例服务质量很高。期待后续的测试补齐和产品化演进 🚀

@qin-ctx
Copy link
Collaborator

qin-ctx commented Mar 5, 2026

/review

1 similar comment
@qin-ctx
Copy link
Collaborator

qin-ctx commented Mar 5, 2026

/review

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 Security concerns

Path traversal vulnerability:
The static asset serving endpoint at /console/{path:path} (examples/console/app.py lines 278-286) constructs file paths using user-supplied path without ensuring the resulting file is within the static directory. This could allow attackers to access arbitrary files on the server (e.g., via ../app.py).

⚡ Recommended focus areas for review

CORS Misconfiguration

The CORS middleware uses allow_credentials=True with allow_origins defaulting to ["*"], which is invalid per browser CORS policies and will cause requests to fail.

app.add_middleware(
    CORSMiddleware,
    allow_origins=config.cors_origins,
    allow_methods=["*"],
    allow_headers=["*"],
    allow_credentials=True,
)
Path Traversal Risk

The static asset endpoint does not safely validate that requested files are within the static directory, which could allow access to files outside the intended directory.

@app.get("/console/{path:path}", include_in_schema=False)
async def console_assets(path: str):
    if path.startswith("api/"):
        return _error_response(status_code=404, code="NOT_FOUND", message="Not found")

    requested_file = static_dir / path
    if requested_file.exists() and requested_file.is_file():
        return FileResponse(requested_file)
    return FileResponse(index_file)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants